#include "Camera.h"

#define SQR(x) (x*x)

/***************************************************************************************/

void CCamera::InitCamera()
{
	m_defaultParams.position = vec3(0,0,0);
	m_defaultParams.viewDir = vec3(0,0,-1);
	m_defaultParams.rightVector = vec3(1,0,0);
	m_defaultParams.upVector = vec3(0,1,0);

	ResetCameraParameters();
}

void CCamera::ResetCameraParameters()
{ 
	m_currentParams = m_defaultParams;

	PitchUp(-30);
	MoveForward(-300);
}

void CCamera::Move (vec3 direction)
{
	m_currentParams.position = m_currentParams.position + direction;
}

void CCamera::PitchUp (GLfloat angle)
{
	//Rotate viewdir around the right vector:
	m_currentParams.viewDir = normalize(m_currentParams.viewDir*cos(angle*DegreesToRadians)
								+ m_currentParams.upVector*sin(angle*DegreesToRadians));

	//now compute the new m_currentParams.upVector (by cross product)
	m_currentParams.upVector = cross(m_currentParams.viewDir, m_currentParams.rightVector)*-1;
}

void CCamera::HeadRight (GLfloat angle)
{
	//Rotate viewdir around the up vector:
	m_currentParams.viewDir = normalize(m_currentParams.viewDir*cos(-angle*DegreesToRadians)
								- m_currentParams.rightVector*sin(-angle*DegreesToRadians));

	//now compute the new m_currentParams.rightVector (by cross product)
	m_currentParams.rightVector = cross(m_currentParams.viewDir, m_currentParams.upVector);
}

void CCamera::RollRight (GLfloat angle)
{
	//Rotate viewdir around the right vector:
	m_currentParams.rightVector = normalize(m_currentParams.rightVector*cos(angle*DegreesToRadians)
								+ m_currentParams.upVector*sin(angle*DegreesToRadians));

	//now compute the new m_currentParams.upVector (by cross product)
	m_currentParams.upVector = cross(m_currentParams.viewDir, m_currentParams.rightVector)*-1;
}

vec3 CCamera::GetOrigin()
{
	return m_currentParams.position + m_currentParams.viewDir;
}

mat4 CCamera::GetViewMatrix( void )
{
	//The point at which the camera looks
	vec3 at3 = m_currentParams.position + m_currentParams.viewDir;
	vec4 at4 = createVec4FromVec3(at3, 0);

	vec4 camera4 = createVec4FromVec3(m_currentParams.position, 1);
	vec4 up4 = createVec4FromVec3(m_currentParams.upVector, 0);

	return LookAt( camera4, at4, up4 );
}

void CCamera::MoveForward( GLfloat Distance )
{
	m_currentParams.position = m_currentParams.position + (m_currentParams.viewDir*Distance);
}

void CCamera::StrafeRight ( GLfloat Distance )
{
	m_currentParams.position = m_currentParams.position + (m_currentParams.rightVector*Distance);
}

void CCamera::MoveUpward( GLfloat Distance )
{
	m_currentParams.position = m_currentParams.position + (m_currentParams.upVector*Distance);
}